﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Game
{
    public class StateBase : State
    {
        private DataBase.Manager mDataBaseManager = null;

        public StateBase(DataBase.Manager db)
        {
            mDataBaseManager = db;
        }

        public UI.IProgressBar ProgressBar
        {
            get;
            set;
        }

        public WorldScene GameScene
        {
            get;
            set;
        }

        public DataBase.Manager DataBaseManager
        {
            get { return mDataBaseManager; }
        }


        //internal System.IO.TextWriter ResWriter = null;

        public IDK.SceneNode AddMapObject(DataBase.Entities.MapObject item, Dictionary<uint, IDK.SceneNode> parentList)
        {
            //if (ResWriter == null)
            //{
            //    ResWriter = System.IO.File.CreateText(@"p:\demo_build.bat");
            //}
            //prepare
            DataBase.Entities.Model dbModel = DataBaseManager.GetModelByID(item.modelId);
            DataBase.Entities.Mesh dbMesh = DataBaseManager.GetMeshByID(dbModel.meshId);
            DataBase.Entities.Material dbMaterial = DataBaseManager.GetMaterialByID(dbModel.materialId);
            //load model
            //...

            //create scene object by db model
            IDK.SceneObject obj = GameScene.Core.GetSceneObject(dbModel.name);
            if (obj == null) // is null than create
            {
                obj = GameScene.Core.AddSceneObject(dbModel.name);

                IDK.Material mat = GameScene.Core.GetMaterial(dbMaterial.name);
                mat.SetShaderProgram(GameScene.Technique.BaseShader);

                IDK.Material.TextureMode layerCount = DataBaseManager.GetTextureCountByMaterialId(dbModel.materialId);

                for (IDK.Material.TextureMode layer = 0; layer != layerCount; ++layer)
                {
                    DataBase.Entities.MaterialIndex matIndex = DataBaseManager.GetMaterialIndex(dbModel.materialId, layer);

                    DataBase.Entities.Texture dbTexture = DataBaseManager.GetTextureByID(matIndex.textureId);

                   // ResWriter.Write(" xcopy \"" + System.IO.Path.GetDirectoryName(@"P:\Resources\Textures\" + dbTexture.path + ".x") + "\\*.*\" \"" + System.IO.Path.GetDirectoryName(@"P:\Demo\Resources\Textures\" + dbTexture.path + ".x") + "\\\" /Y \n");
                    //Add texture
                    mat.SetTexture(layer,
                        GameScene.Core.AddTexture(
                        dbTexture.path,
                        dbTexture.format,
                        IDK.Texture.PixelType.ByteRGBA8,
                        dbTexture.mipCount, 
                        dbTexture.width,
                        dbTexture.height));
                }

                obj.SetMaterial(mat);

                //load mesh
                //...
                //ResWriter.Write(" xcopy \"" + System.IO.Path.GetDirectoryName(@"P:\Resources\Meshes\" + dbMesh.path + ".x") + "\\*.*\" \"" + System.IO.Path.GetDirectoryName(@"P:\Demo\Resources\Meshes\" + dbMesh.path + ".x") + "\\\" /Y \n");
                //ResWriter.Flush();  
                IDK.Mesh mesh = GameScene.Core.GetMesh(dbMesh.path);
                obj.SetMesh(mesh);
            }

            //Scene
            IDK.SceneNode node = null;

            if (item.parentId == 0 || parentList == null)
            {
                node = GameScene.Core.GetScene().AddNode(item.name, GameScene.Technique.RootObjectSceneNode);
            }
            else
            {
                node = GameScene.Core.GetScene().AddNode(item.name, parentList[item.parentId]);
            }

            //add to parentList
            if (parentList != null)
            {
                parentList.Add(item.id, node);
            }

            IDK.Quaternion q = new IDK.Quaternion(item.qW, item.qX, item.qY, item.qZ);

            IDK.Vector3 min = new IDK.Vector3(dbMesh.minX, dbMesh.minY, dbMesh.minZ);
            IDK.Vector3 max = new IDK.Vector3(dbMesh.maxX, dbMesh.maxY, dbMesh.maxZ);

            IDK.Vector3 pos = new IDK.Vector3(item.posX, item.posY, item.posZ);
            node.MakeTransformation(pos, q, new IDK.AABBox(min, max), new IDK.Vector3(item.scale));

            node.AddRenderable(obj);

            return node;
        }
    }
}
